package com.uam.core.business;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.uam.core.config.UAMConfig;
import com.uam.core.entity.enums.FlyModes;
import com.uam.core.entity.enums.RouteParams;
import com.uam.core.entity.enums.SpatialLevels;
import com.uam.core.entity.model.AircraftModel;
import com.uam.core.entity.model.TaskModel;
import com.uam.core.entity.uitls.HttpUtil;
import com.uam.core.service.RouteService;
import org.locationtech.jts.geom.Polygon;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Administrator
 */
public class SmartRouteUtils {

    /**
     * 获取航线信息
     * @param config
     * @param aircraft
     * @param task
     * @param routeService
     * @return
     */
    public static RouteService.RouteResultWithAircraftPositions smartRoute(
            UAMConfig config,
            AircraftModel aircraft,
            TaskModel task,
            RouteService routeService) {

        JSONArray settings = JSON.parseArray(task.getSettings());
        JSONArray startPoint = ((JSONObject) settings.remove(0)).getJSONArray("position");
        double startAltitude = startPoint.getDoubleValue(2);
        double altitude = startAltitude;
        double endAltitude = settings.getJSONObject(settings.size() - 1).getJSONArray("position").getDoubleValue(2);
        if (altitude < endAltitude) {
            altitude = endAltitude;
        }
        int mode = task.getMode();
        double minAltitude = aircraft.getMinAltitude();
        double maxAltitude = aircraft.getMaxAltitude();
        if (config.isAltitudeNeedBase()) {
            minAltitude = minAltitude + altitude;
            maxAltitude = maxAltitude + altitude;
        }
        double safeDistance = aircraft.getSafeDistance();
        int i = 0;
        int j = 0;
        int size = settings.size();
        double[][] points = new double[size + 1][];
        points[i++] = routeService.position2Array(startPoint);
        while (i <= size) {
            com.alibaba.fastjson.JSONArray coordinate = settings.getJSONObject(j++).getJSONArray("position");
            points[i++] = new double[]{coordinate.getDoubleValue(0), coordinate.getDoubleValue(1)};
        }
        i = 0;
        Map<String, Object> params = new HashMap<String, Object>();
        RouteParams[] routeParams = RouteParams.values();
        size = routeParams.length;
        while (i < size) {
            RouteParams routeParam = routeParams[i++];
            Object defaultValue = routeParam.getDefaultValue();
            if (defaultValue != null) {
                params.put(routeParam.getName(), defaultValue);
            }
        }
        params.put(RouteParams.FLIGHT_TYPE.getName(), String.valueOf(mode));
        params.put(RouteParams.MIN_HEIGHT.getName(), String.valueOf((int) minAltitude));
        params.put(RouteParams.MAX_HEIGHT.getName(), String.valueOf((int) maxAltitude));
        params.put(RouteParams.POINTS.getName(), points);

        JSONObject jsonObjectHttp = null;
        List<Map<String, Object>> aircraftPositions = null;
        if (FlyModes.ROAD_NET.getCode() == mode) {
            jsonObjectHttp = HttpUtil.postRequest(config.getRoadNetRouteUrl(), params);
        } else {
            if (FlyModes.FREE.getCode() == mode) {
                List<Polygon> obstacleAreas = new ArrayList<>();
                aircraftPositions = routeService.obstacleAreas(minAltitude, safeDistance, maxAltitude, points, obstacleAreas);
                if (obstacleAreas != null) {
                    params.put(RouteParams.OBSTACLE_VOS.getName(), routeService.buildObstacleAreas(obstacleAreas));
                }
            }
            jsonObjectHttp = HttpUtil.postRequest(config.getAirRouteUrl(), params);
        }
        if(!checkDataHttp(jsonObjectHttp,routeService,task)){
            return null;
        }

        JSONArray routes = jsonObjectHttp.getJSONArray("paths");
        int routeNum = routes.size();

        //选择航线，最优航线
        JSONObject route = routeService.pickRoute(altitude + safeDistance, (aircraft.getSpeed() / 3.60D) * (aircraft.getMaxDuration() * 60.00D), routeNum, routes);

        if(!checkRouteHttpPoint(route,routeService,task)){
            return null;
        }

        route.put("startAltitude", startAltitude);
        route.put("endAltitude", endAltitude);
        RouteService.RouteResultWithAircraftPositions positions = new RouteService.RouteResultWithAircraftPositions(route, aircraftPositions);
        return positions;
    }

    private  static boolean checkDataHttp(JSONObject jsonObjectHttp, RouteService routeService, TaskModel task) {
        if (jsonObjectHttp == null) {
            routeService.handleRejectedResult(task.getId(), "调用航线信息返回为空！", null);
            return false;
        }
        JSONArray paths = jsonObjectHttp.getJSONArray("paths");

        if (paths == null || paths.size() == 0) {
            routeService.handleRejectedResult(task.getId(), "航线信息为0！", null);
        }
        return true;
    }

    private static boolean checkRouteHttpPoint(JSONObject rote, RouteService routeService, TaskModel task) {
        JSONObject track = rote.getJSONObject("points");
        if (track == null) {
            routeService.handleRejectedResult(task.getId(), "航线返回轨迹点不存在！", null);
            return false;
        }

        JSONArray trackCoordinates = track.getJSONArray("coordinates");
        if (trackCoordinates == null || trackCoordinates.size() == 0) {
            routeService.handleRejectedResult(task.getId(), "航线返回轨迹点为空！", null);
            return false;
        }
        return true;
    }

}
